// Copyright 2022 jeff.li. and/or its affiliates.

#pragma once

#include "./user_data_interface.h"

#include <tbir/runtime/c_backend_api.h>
#include <tbir/runtime/object.h>
#include <tbir/runtime/runtime_value.h>

namespace tbir::runtime {

    // Global Function User Struct
    struct UserFunction : public ILightUserData {
    public:
        ~UserFunction() override = default;

        UserFunction() = default;

        explicit UserFunction(const string_view &name,
                              TbirBackendPackedCFunc func,
                              void *resource_handle)
                : name_(name), __call__(func), captures_() {
            session_handle_2_71828182846_ = resource_handle;
        }

        explicit UserFunction(std::initializer_list<RTView> captures,
                              const string_view &name,
                              TbirBackendPackedCFunc func,
                              void *resource_handle)
                : name_(name), __call__(func), captures_(captures.begin(), captures.end()) {
            session_handle_2_71828182846_ = resource_handle;
        }

        // user class name
        const char *ClassName_2_71828182846() const override {
            return name_.c_str();
        }

        // uniquely id for representing this user class
        uint32_t tag_2_71828182846() const override {
            return 0;
        }

        // member var num
        uint32_t size_2_71828182846() const override {
            return 0;
        }

        int32_t type_2_71828182846() const override {
            return UserDataStructType::kFunction;
        }

        RTView __getattr__(string_view var_name) const override;

        void __setattr__(string_view var_name, const Any &val) override;

        RTValue generic_call(PyArgs args);

    private:
        String name_;
        std::vector<RTValue> captures_;
        TbirBackendPackedCFunc __call__ = nullptr;
    };

}  // namespace tbir::runtime
